package com.dense.kuiniu.floatcabinet.mvp.manager.bord;

import android.util.SparseArray;

import com.kuiniu.serialport.utils.ByteUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Administrator
 * @date 2020/11/17
 */
public class DoorManager {

    private SparseArray<Door> mDoorList = new SparseArray<>();
    private List<Door> mChange2OpenList = new ArrayList<>();
    private List<Door> mChange2CloseList = new ArrayList<>();
    private SparseArray<int[]> numbers = new SparseArray<>();

    /**
     * 板子数量
     */
    private static final int BORD_SIZE = 1;
    /**
     * 一块板子对应的门数量
     */
    public static final int DOOR_NUMBER_BY_ONE_BORD = 8;

    private DoorManager() {
        for (int i = 1; i < BORD_SIZE + 1; i++) {
            int[] d = new int[DOOR_NUMBER_BY_ONE_BORD];
            for (int j = 1; j < DOOR_NUMBER_BY_ONE_BORD + 1; j++) {
                Door door = new Door((i - 1) * DOOR_NUMBER_BY_ONE_BORD + j);
                mDoorList.put(door.getDoorNumber(), door);
                d[j - 1] = j;
            }
            numbers.put(i, d);
        }
    }

    public void init() {

    }


    private static final class Holder {
        private static final DoorManager INSTANCE = new DoorManager();
    }

    public static DoorManager getInstance() {
        return Holder.INSTANCE;
    }

    public Door getDoor(int doorNumber) {
        return mDoorList.get(doorNumber);
    }

    public SparseArray<int[]> getNumbers() {
        return numbers;
    }

    public void updateDoorState(int deviceId, byte[] status) {
        mChange2OpenList.clear();
        mChange2CloseList.clear();
        for (int i = 0; i < mDoorList.size(); i++) {
            int key = mDoorList.keyAt(i);
            Door door = mDoorList.get(key);
            boolean oldStats = door.isOpen();
            boolean isOpen = ByteUtils.getStatus(door.getDoorNumber() - (deviceId - 1) * 16, status);
            door.setOpen(isOpen);
            if (oldStats && !isOpen) {
                //状态不一致，关门
                mChange2CloseList.add(door);
            } else if (!oldStats && isOpen) {
                mChange2OpenList.add(door);
            }

        }
    }

    public void initDoorState(int deviceId, byte[] status) {
        for (int i = 0; i < mDoorList.size(); i++) {
            int key = mDoorList.keyAt(i);
            Door door = mDoorList.get(key);
            boolean isOpen = ByteUtils.getStatus(door.getDoorNumber() - (deviceId - 1) * 16, status);
            door.setOpen(isOpen);
        }
    }

    public void updateDoorEpcListData(int doorNumber, List<String> epcList) {
        Door door = mDoorList.get(doorNumber);
        if (door != null) {
            door.setEpc(epcList);
            door.saveOrUpdate();
        }
    }

    public Door findLeastDataDoor() {
        int index = 0;
        int size = 0;
        for (int i = 0; i < mDoorList.size(); i++) {
            Door door = mDoorList.get(i);
            List<String> epcList = door.getEpc();
            if (epcList == null || epcList.isEmpty()) {
                return door;
            } else {
                if (size < epcList.size()) {
                    size = epcList.size();
                    index = i;
                }
            }
        }
        return mDoorList.get(index);
    }

    public Door getDoorByDoorNumber(int doorNumber) {
        return mDoorList.get(doorNumber);
    }

    public List<Door> getAllDoorList() {
        List<Door> list = new ArrayList<>();
        for (int i = 0; i < mDoorList.size(); i++) {
            list.add(mDoorList.valueAt(i));
        }
        return list;
    }

    public List<Door> getChange2OpenDoorList() {
        return mChange2OpenList;
    }

    public List<Door> getOpenDoorList() {
        List<Door> openList = new ArrayList<>();
        for (int i = 0; i < mDoorList.size(); i++) {
            Door door = mDoorList.valueAt(i);
            if (door.isOpen()) {
                openList.add(door);
            }
        }
        return openList;
    }


    public List<Door> getChange2CloseDoorList() {
        return mChange2CloseList;
    }
}